package org.vsg.common.pagination.processor.hibernate;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

public class HibernatePaginationQuery implements HibernateCallback {
	
	private String query;
	private Object[] params;
	private int startIndex;
	private int rows;
	
	public HibernatePaginationQuery(String query , Object[] params , int startIndex , int rows ) {
		this.query = query;
		this.params = params;
		this.startIndex = startIndex;
		this.rows = rows;
	}
	
	/**
	 * default hibernatpagination
	 *
	 */
	public HibernatePaginationQuery() {
		
	}

	public Object doInHibernate(Session sess) throws HibernateException,
			SQLException {
		// TODO Auto-generated method stub
		Query query = sess.createQuery(this.query);
		query = queryPreparedHandle(query , this.params);
		query.setFirstResult(startIndex);
		query.setMaxResults(rows);
		return query.list();
	}

	/**
	 * @return Returns the params.
	 */
	public Object[] getParams() {
		return params;
	}

	/**
	 * @param params The params to set.
	 */
	public void setParams(Object[] params) {
		this.params = params;
	}

	/**
	 * @return Returns the query.
	 */
	public String getQuery() {
		return query;
	}

	/**
	 * @param query The query to set.
	 */
	public void setQuery(String query) {
		this.query = query;
	}

	/**
	 * @return Returns the rows.
	 */
	public int getRows() {
		return rows;
	}

	/**
	 * @param rows The rows to set.
	 */
	public void setRows(int rows) {
		this.rows = rows;
	}

	/**
	 * @return Returns the startIndex.
	 */
	public int getStartIndex() {
		return startIndex;
	}

	/**
	 * @param startIndex The startIndex to set.
	 */
	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	// primative query
	private Query queryPreparedHandle(Query query , Object[] params) {
		if (params != null) {
			for (int i = 0 ; i < params.length ;i++) {
				Object param = params[i];
				// check the parameter is null or not!
				if (param != null) {
					
					if (param instanceof byte[]) {
						query.setBinary(i,(byte[])param);
					}
					
					else if (param instanceof BigDecimal) {
						query.setBigDecimal(i , (BigDecimal)param);						
					}

					else if (param instanceof BigInteger) {
						query.setBigInteger(i , (BigInteger)param);						
					}
					
					else if (param instanceof Boolean) {
						boolean value = ((Boolean)param).booleanValue();
						query.setBoolean(i , value);						
					}

					else if (param instanceof Byte) {
						byte value = ((Byte)param).byteValue();
						query.setByte(i , value);						
					}					

					else if (param instanceof Character) {
						char value = ((Character)param).charValue();
						query.setCharacter(i , value);						
					}	

					else if (param instanceof Double) {
						double value = ((Double)param).doubleValue();
						query.setDouble(i , value);						
					}					
					
					else if (param instanceof Float) {
						float value = ((Float)param).floatValue();
						query.setFloat(i , value);						
					}	

					else if (param instanceof Integer) {
						int value = ((Integer)param).intValue();
						query.setInteger(i , value);						
					}						

					else if (param instanceof Long) {
						long value = ((Long)param).longValue();
						query.setLong(i , value);						
					}					

					else if (param instanceof Short) {
						short value = ((Short)param).shortValue();
						query.setShort(i , value);						
					}					
					
					else if (param instanceof Calendar) {
						Calendar value = (Calendar)param;
						query.setCalendarDate(i , value);						
					}					

					else if (param instanceof Date) {
						Date value = (Date)param;
						query.setDate(i , value);						
					}					

					else if (param instanceof String) {
						String value = (String)param;
						query.setString(i , value);						
					}					
					
				}
			}
		}
		return query;
	}	
}
